`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    16:25:17 10/21/2012 
// Design Name: 
// Module Name:    Minor_FSM_B 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module Minor_FSM_B(clk, reset, start, increase_Incrash,paddle_y, 
ini_speed_x, ini_speed_y,ball_x, ball_y,speed_x, speed_y,
dir_x_o, dir_y_o, game_Over,ControlEstado
);
	input clk, reset, start, increase_Incrash;
	input [9:0] paddle_y;
	input [5:0] ini_speed_x, ini_speed_y;
	input [9:0]  ball_x, ball_y;
	output reg[5:0] speed_x, speed_y;
	output reg dir_x_o, dir_y_o, game_Over;
	output ControlEstado;
	localparam [2:0] PADDLEWIDTH = 5; //bits
	localparam [9:0] PADDLELONG = 82;
	localparam [9:0] PADDLE_X = 28; 
	localparam [9:0] PADDLE_SEC = PADDLELONG/6;
		
	localparam [9:0] MAX_X = 640;
	localparam [9:0] MAX_Y = 400;
	localparam [5:0] BORDER = 8;
	localparam [5:0] BALL_SIZE = 5;
	
	reg ControlEstado;
	initial begin
		ControlEstado= 0;
	end
	
	// Increase in paddle crash logic
	reg [1:0] crash_plus1, crash_plus2, crash_plus3; 
	initial begin
		crash_plus1=0;
		crash_plus2=0;
		crash_plus3=0;
	end
		
	parameter state0 = 2'b00;  //T1
   parameter state1 = 2'b01;  //T2
   parameter state2 = 2'b10;  //T3
	parameter state3 = 2'b11;  //T3
	reg [1:0] state = state0;

   always@(posedge clk)
      if (reset) 
		begin
         state <= state0;
         speed_x <= ini_speed_x;
			speed_y <= ini_speed_y;
			dir_x_o <= 1;
			dir_y_o <= 1;
			game_Over <= 0;
			if(increase_Incrash)
			begin
				crash_plus1 <= 0;
				crash_plus2 <= 0;
				crash_plus3 <= 0;
			end
			else
			begin
				crash_plus1 <= 1;
				crash_plus2 <= 2;
				crash_plus3 <= 3;
			end
      end
		else if(ControlEstado)
			ControlEstado<=0;
		
      else
         case (state)
            state0 :
				begin		
					ControlEstado <= 0;
               if (start)
					begin
                  state <= state1;
					end
               else
                  state <= state0;
            end				
            state1 :  // Paddle crash
				begin
               if (ball_x <= (PADDLE_X+PADDLEWIDTH+1) && ball_y >= paddle_y && ball_y <= (paddle_y+PADDLELONG)) 
						begin
							if ((paddle_y <= ball_y && ball_y < paddle_y+PADDLE_SEC) || 
								 (paddle_y+(6*PADDLE_SEC) <= ball_y && ball_y < paddle_y+(7*PADDLE_SEC)))
							begin
								speed_y <= speed_y + crash_plus3; 
								speed_x <= speed_x + crash_plus1;								
							end
							else if ((paddle_y+PADDLE_SEC <= ball_y && ball_y < paddle_y+(2*PADDLE_SEC)) || 
										(paddle_y+(5*PADDLE_SEC) <= ball_y && ball_y < paddle_y+(6*PADDLE_SEC)))
							begin
								speed_y <= speed_y + crash_plus2;
								speed_x <= speed_x + crash_plus1;
							end
							else if ((paddle_y+PADDLE_SEC <= ball_y && ball_y < paddle_y+(2*PADDLE_SEC)) || 
										(paddle_y+(4*PADDLE_SEC) <= ball_y && ball_y < paddle_y+(5*PADDLE_SEC)))
							begin
								speed_y <= speed_y + crash_plus1;
								speed_x <= speed_x + crash_plus2;
							end
							else if ((paddle_y+(2*PADDLE_SEC) <= ball_y && ball_y < paddle_y+(3*PADDLE_SEC)) || 
										(paddle_y+(3*PADDLE_SEC) <= ball_y && ball_y < paddle_y+(4*PADDLE_SEC)))
							begin
								speed_x <= speed_x + crash_plus3;
							end		
							
							dir_x_o <= ~ dir_x_o;
							state <= state3;
						end
					else
						state <= state2;
            end
				
            state2 : // wall crash
				begin
               if(game_Over) 
						state <= state2;					
               else if ((ball_y-speed_y <= BORDER+1) || (ball_y+speed_y >= (MAX_Y-(BORDER+1)-BALL_SIZE))) 
					begin	
						dir_y_o <= ~dir_y_o;
						state <= state3;
					end
					else if (ball_x+speed_x >= MAX_X-(BORDER+1)-BALL_SIZE)
					begin
						dir_x_o <= ~dir_x_o;
						state <= state3;
					end
					else if (ball_x <= PADDLE_X)
					begin
						game_Over <= 1;
						state <= state2;
					end
					else
						state <= state3;
            end
				state3 : 
				begin
					ControlEstado <= 1;
					state <= 0;
				end
            default: begin  
               state <= state0;
					speed_x <= ini_speed_x;
					speed_y <= ini_speed_y;
					dir_x_o <= 1;
					dir_y_o <= 1;
					game_Over <= 0;
					ControlEstado <= 0;
				end
			endcase

endmodule	




